package com.sinosoft.msf.base.supplier.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sinosoft.msf.base.supplier.dao.base.*;
import com.sinosoft.msf.base.supplier.expection.BizException;
import com.sinosoft.msf.base.supplier.pojo.*;
import com.sinosoft.msf.base.supplier.pojo.entity.*;
import com.sinosoft.msf.base.supplier.pojo.tyc.AutoReviewResVo;
import com.sinosoft.msf.base.supplier.props.ComStateEnum;
import com.sinosoft.msf.base.supplier.props.IpAddressEnum;
import com.sinosoft.msf.base.supplier.props.ProjectStateEnum;
import com.sinosoft.msf.base.supplier.props.SupProps;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class ProjectService {
    @Autowired
    SProjectInfoMapper sProjectInfoMapper;
    @Autowired
    SProjectCompanyMapper sProjectCompanyMapper;
    @Autowired
    SCompanyInfoMapper sCompanyInfoMapper;
    @Autowired
    SCompanyContractMapper contractMapper;
    @Autowired
    CommonInterService commonInterService;
    @Autowired
    SupSendService sendService;
    @Autowired
    CommonBizService commonBizService;
    @Autowired
    SProjectSignMapper signMapper;
    @Autowired
    SupProps supProps;
    @Autowired
    SCompanyMapper sCompanyMapper;
    @Autowired
    CompanyNoticeService companyNoticeService;
    public static String bizType = "project";
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 保存项目
     *
     * @param projectInfoPojo 项目信息
     * @return 保存结果
     */
    @Transactional
    public CodeNameVo save(ProjectInfoPojo projectInfoPojo, OptVo optVo, String proId, Consumer<SProjectInfo> consumer, List<SProjectCompany> sProjectCompanies, SProjectInfo orgInfo) {
        Map<String, SProjectCompany> comMap = new HashMap<>();
        for (SProjectCompany sProjectCompany : sProjectCompanies) {
            comMap.put(sProjectCompany.getCompanyId(), sProjectCompany);
        }
        String state;
        String msg = "提交成功";
        String url = "";
//        String qaFail = "";

        boolean hasSign = signState.contains(orgInfo.getHisSignState());
        //创建项目
        SProjectInfo sProjectInfo = new SProjectInfo();
        BeanUtil.copyProperties(projectInfoPojo, sProjectInfo);
        sProjectInfo.setId(proId);
        sProjectInfo.setAuditId("");//审核人
        sProjectInfo.setDeleted("n");
        sProjectInfo.setCreatedName(optVo.getUserName());
        sProjectInfo.setCreatedId(optVo.getUserId());
        sProjectInfo.setCreatedDate(new Date());
        sProjectInfo.setUpdateId("");
        sProjectInfo.setUpdateDate(new Date());
        List<SProjectCompany> addList = new ArrayList<>();
        List<CompanyInfoPojo> companyInfoPojoList = projectInfoPojo.getCompanys();
        companyInfoPojoList.forEach(company -> {
            SProjectCompany sProjectCompany = new SProjectCompany();
            sProjectCompany.setId(IdUtil.simpleUUID());
            sProjectCompany.setProjectId(sProjectInfo.getId());
            sProjectCompany.setCompanyId(company.getId());
            String sta = "n";
            //如果操作的是签报打会的项目，则保留原来的选中状态
            if (hasSign) {
                SProjectCompany orgComInfo = comMap.get(company.getId());
                if (orgComInfo != null) {
                    sta = orgComInfo.getStatus();
                    sProjectCompany.setPrice(orgComInfo.getPrice());
                    sProjectCompany.setPriceDate(orgComInfo.getPriceDate());
                    sProjectCompany.setPriceFile(orgComInfo.getPriceFile());
                    sProjectCompany.setPriceIp(orgComInfo.getPriceIp());
                }
                SCompanyInfo sCompanyInfo = sCompanyInfoMapper.selectByPrimaryKey(company.getId());
                if (!"n".equals(sCompanyInfo.getModId())) {
                    sProjectCompany.setCompanyModId(sCompanyInfo.getModId());
                }
            }
            sProjectCompany.setStatus(sta);
            sProjectCompany.setDeleted("n");
            sProjectCompany.setCreatedId(optVo.getUserId());
            sProjectCompany.setCreatedDate(new Date());
            addList.add(sProjectCompany);
        });
        //进行供应商资质审核
        List<CompanyInfoPojo> companyInfoPojos = new ArrayList<>();
        List<AutoReviewResVo> autoReviewResVos = new ArrayList<>();
        //相同人员信息/ip地址校验
        if (companyInfoPojoList.size() > 1) {
            String companyPersonCompare = commonInterService.companyPersonCompare(companyInfoPojoList);
            if (!StringUtils.isEmpty(companyPersonCompare)) {
                throw new BizException(companyPersonCompare + "，无法发起项目，请更换供应商或与采购管理员联系");
            }
        }
        for (CompanyInfoPojo company : companyInfoPojoList) {
            //查询供应商的统一社会信用代码
            SCompanyInfo sCompanyInfo = sCompanyInfoMapper.selectByPrimaryKey(company.getId());
            if (sCompanyInfo == null) {
                throw new BizException("该" + company.getName() + "供应商不存在");
            }
            List<CompanyInfoPojo.ScopeItem> scopeItems = commonBizService.queryScopeById(company.getId());
            boolean hasSameScope = scopeItems.stream().anyMatch(a -> a.getStrCode().contains(sProjectInfo.getProjectCat()));
            if (!hasSameScope) {
                throw new BizException("该" + company.getName() + "供应商范围与项目不一致，请重新选择");
            }
            // 新增供应商若修改信息校验：供应商状态为未审核通过
            if (!ComStateEnum.PASS.name().equals(sCompanyInfo.getState())) {
                throw new BizException(company.getName() + "供应商信息已发生变化，请待供应商信息审核通过后再进行项目审核");
            }
            //供应商标记状态审核
            if (!commonInterService.markReview(sCompanyInfo)) {
                throw new BizException(company.getName() + "当前是非启用状态，请更换供应商！若仍需该供应商参与项目，请联系管理员！");
            }
            //查询天眼查企业最新信息进行资质审核
            EnterpriseInfoPojo enterpriseInfoPojo = commonInterService.queryTYCInfo(sCompanyInfo.getSocialCreditCode());
            //资质审核
            AutoReviewResVo resVo = commonInterService.autoReview(enterpriseInfoPojo);
            autoReviewResVos.add(resVo);
            if (resVo.getState() ==1){
                throw new BizException(company.getName()+"供应商存在异常，不可参与项目");
            }
            //判断天眼查最新的企业基本信息与供应商主表里的核对是否一致
            if (!commonInterService.basicInfoCompare(sCompanyInfo, enterpriseInfoPojo)) {
                throw new BizException(company.getName() + "供应商企业基本信息有变化，请供应商信息修改后再行项目");
            }
            CompanyInfoPojo companyInfoPojo = new CompanyInfoPojo();
            BeanUtil.copyProperties(enterpriseInfoPojo, companyInfoPojo);
            companyInfoPojo.setId(company.getId());
            companyInfoPojos.add(companyInfoPojo);
        }
        //判断供应商有无关联关系
        AutoReviewResVo assResVo = commonInterService.checkAssociation(companyInfoPojos);
        autoReviewResVos.add(assResVo);
        boolean hasErrorState = autoReviewResVos.stream().anyMatch(autoReviewResVo -> autoReviewResVo.getState() != 0);
        if(hasErrorState){
            state = ProjectStateEnum.qaf.name();
//            sendService.sendWechat(ProjectStateEnum.qaf.name(), "您好，请尽快登陆费控平台进行供应商资质审核");
            msg = autoReviewResVos.stream().map(AutoReviewResVo::getMsg).flatMap(Collection::stream).collect(Collectors.joining(";\n"));
            addAuditRecord(optVo, sProjectInfo, "qa", "n", msg);
        }else{
            if (hasSign) {
                //如果是签报驳回的，执行重新签报逻辑
                state = ProjectStateEnum.siw.name();

            }else{
                state = ProjectStateEnum.qap.name();
            }

            addAuditRecord(optVo, sProjectInfo, "qa", "y", "资质审核通过");
        }
        sProjectInfo.setStatus(state);
        consumer.accept(sProjectInfo);
        sProjectCompanyMapper.insertList(addList);
        if (ProjectStateEnum.siw.name().equals(state)){
            // 签报驳回重新提交签报前更新关联表的modId
//            companyInfoPojoList.forEach(company -> {
//                SCompanyInfo sCompanyInfo = sCompanyInfoMapper.selectByPrimaryKey(company.getId());
//                if (!"n".equals(sCompanyInfo.getModId())) {
//                    sCompanyMapper.updateCompanyModifyId(sCompanyInfo.getModId(), sProjectInfo.getId(), company.getId());
//                }
//            });
//            logger.info("签报驳回重新提交签报前更新关联表的modId完成");
//            url = toSign(projectInfoPojo,optVo,info->{});
        }
        CodeNameVo vo = new CodeNameVo();
        vo.setId(sProjectInfo.getId());
        vo.setCode(sProjectInfo.getStatus());
        vo.setName(msg);
        vo.setUrl(url);
        return vo;
    }
    /**
     * 编辑项目
     * **/
    @Transactional
    public CodeNameVo editProject(ProjectInfoPojo projectInfoPojo, OptVo optVo) {
        List<SProjectCompany> sProjectCompanies = querySelectedProjectComs(projectInfoPojo.getId());


        delProComs(projectInfoPojo.getId());
        Consumer<SProjectInfo> consumer = info->{
            info.setProReport("");
            sProjectInfoMapper.updateByPrimaryKeySelective(info);
        };
        SProjectInfo orgInfo = queryProjectById(projectInfoPojo.getId());
        return save(projectInfoPojo, optVo, projectInfoPojo.getId(), consumer,sProjectCompanies,orgInfo);
    }
    /**
     * 暂存项目
     * **/
    @Transactional
    public String stagSave(ProjectInfoPojo projectInfoPojo,OptVo optVo) {
        String state = "stg";
        String msg = "提交成功";
        //创建项目
        boolean isAdd = true;
        String proId = IdUtil.simpleUUID();
        if (StrUtil.isNotEmpty(projectInfoPojo.getId())) {
            proId = projectInfoPojo.getId();
            isAdd = false;
        }
        SProjectInfo sProjectInfo = new SProjectInfo();
        BeanUtil.copyProperties(projectInfoPojo, sProjectInfo);
        sProjectInfo.setId(proId);
        sProjectInfo.setAuditId("");//审核人
        sProjectInfo.setStatus(state);
        sProjectInfo.setDeleted("n");
        sProjectInfo.setCreatedName(optVo.getUserName());
        sProjectInfo.setCreatedId(optVo.getUserId());
        sProjectInfo.setCreatedDate(new Date());
        sProjectInfo.setUpdateId("");
        sProjectInfo.setUpdateDate(new Date());

        List<SProjectCompany> addList = new ArrayList<>();
        List<CompanyInfoPojo> companyInfoPojoList = projectInfoPojo.getCompanys();
        companyInfoPojoList.forEach(company -> {
            SProjectCompany sProjectCompany = new SProjectCompany();
            sProjectCompany.setId(IdUtil.simpleUUID());
            sProjectCompany.setProjectId(sProjectInfo.getId());
            sProjectCompany.setCompanyId(company.getId());
            sProjectCompany.setStatus("n");
            sProjectCompany.setDeleted("n");
            sProjectCompany.setCreatedId(optVo.getUserId());
            sProjectCompany.setCreatedDate(new Date());
            addList.add(sProjectCompany);
        });
        if(isAdd){
            sProjectInfoMapper.insert(sProjectInfo);
            if (CollUtil.isNotEmpty(addList)) {
                sProjectCompanyMapper.insertList(addList);
            }
        }else{
            sProjectInfoMapper.updateByPrimaryKeySelective(sProjectInfo);
            Example exp = new Example(SProjectCompany.class, true, true);
            exp.createCriteria().andEqualTo("projectId",proId);
            sProjectCompanyMapper.deleteByExample(exp);
            if (CollUtil.isNotEmpty(addList)) {
                sProjectCompanyMapper.insertList(addList);
            }
        }
        return msg;
    }
    @Transactional
    public CodeNameVo saveProject(ProjectInfoPojo projectInfoPojo,OptVo optVo) {
        Consumer<SProjectInfo> consumer = info->{
            sProjectInfoMapper.insert(info);
        };
        List<SProjectCompany> selectList = new ArrayList<>();
        return save(projectInfoPojo,optVo, IdUtil.simpleUUID(), consumer,selectList,new SProjectInfo());
    }
    @Transactional
    public void delProject(String id) {
        SProjectInfo info = new SProjectInfo();
        info.setId(id);
        info.setDeleted("y");
        sProjectInfoMapper.updateByPrimaryKeySelective(info);
        delProComs(id);
    }

    private void delProComs(String id) {
        SProjectCompany projectCompany = new SProjectCompany();
        projectCompany.setDeleted("y");
        Example exp = new Example(SProjectCompany.class, true, true);
        exp.createCriteria().andEqualTo("projectId", id);
        sProjectCompanyMapper.updateByExampleSelective(projectCompany,exp);
    }

    public void updateReport(String id,String report) {
        SProjectInfo projectInfo = new SProjectInfo();
        projectInfo.setId(id);
        projectInfo.setProReport(report);
        sProjectInfoMapper.updateByPrimaryKeySelective(projectInfo);
    }
    public ProjectInfoPojo detail(String id,boolean cdnEncode) {
        SProjectInfo sProjectInfo = sProjectInfoMapper.selectByPrimaryKey(id);
        if (sProjectInfo == null) {
            throw new BizException("不存在该项目");
        }
        List<SProjectCompany> companyList = queryProjectComs(id);
        Map<String, List<String>> sameIPMap = calSameIP(companyList);
        Map<String, String> idNameMap = new HashMap<>();
        ProjectInfoPojo infoPojo = new ProjectInfoPojo();
        BeanUtil.copyProperties(sProjectInfo, infoPojo);
        List<String> selectIds = new ArrayList<>();
        List<CompanyInfoPojo> companyInfoPojos = new ArrayList<>();

        for (SProjectCompany com : companyList) {
            //todo 此处修改逻辑，如果有modId查修改表
            CompanyInfoPojo pojo;
            if (!StringUtils.isEmpty(com.getCompanyModId())) {
                pojo = commonBizService.queryCompanyDetail("", com.getCompanyModId(), "", cdnEncode);
            } else {
                pojo = commonBizService.queryCompanyDetail(com.getCompanyId(), "", "", cdnEncode);
            }
            idNameMap.put(pojo.getId(), pojo.getName());
//            if (cdnEncode) {
//                com.setPriceFile(CdnEncryUtil.toCdnUrl(com.getPriceFile()));
//            }else{
//                com.setPriceFile(CdnEncryUtil.toObsUrl(com.getPriceFile()));
//            }
            pojo.setProjectCompany(com);
            if("y".equals(com.getStatus())){
                pojo.setSucBidder("y");
                selectIds.add(com.getId());
            }
            companyInfoPojos.add(pojo);
        }
        for (CompanyInfoPojo companyInfoPojo : companyInfoPojos) {
            List<String> list = sameIPMap.get(companyInfoPojo.getId());
            if (CollUtil.isNotEmpty(list)) {
                logger.info("存在IP重复的供应商");
                String collect = list.stream().map(idNameMap::get).collect(Collectors.joining("、"));
                companyInfoPojo.setIpSame(collect);
            }
        }
        infoPojo.setSelectedIds(selectIds);
        Example exp = new Example(SCompanyFile.class);
        exp.createCriteria()
                .andEqualTo("bizType", bizType)
                .andEqualTo("bizId", sProjectInfo.getId())
                .andEqualTo("deleted", "n")
                .andEqualTo("fileType", "price");
        //将原来的报价单文件逻辑删除
        //项目文件
        List<SCompanyFile> sCompanyFiles = fileMapper.selectByExample(exp);
        sCompanyFiles.forEach(file->{
//            if (cdnEncode) {
//                file.setFilePath(CdnEncryUtil.toCdnUrl(file.getFilePath()));
//            }else{
//                file.setFilePath(CdnEncryUtil.toObsUrl(file.getFilePath()));
//            }
        });
        infoPojo.setCompanyFiles(sCompanyFiles);
        infoPojo.setCompanys(companyInfoPojos);
        //审核记录
        List<SAuditRecord> recordMap = queryAuditRecord(id);
        infoPojo.setRecord(recordMap);
        return infoPojo;
    }
    public Map<String, List<String>> calSameIP(List<SProjectCompany> companyInfoPojos) {
        Map<String, List<String>> repeatMap = new HashMap<>();

        if (CollUtil.isEmpty(companyInfoPojos)) {
            return repeatMap;
        }
        Map<String, List<SProjectCompany>> collect = companyInfoPojos.stream()
                .filter(a -> StrUtil.isNotEmpty(a.getPriceIp()) && a.getPriceIp().split("\\.").length == 4)
                .map(a -> {
                    SProjectCompany com = new SProjectCompany();
                    String afterIp = String.join(".", Arrays.copyOfRange(a.getPriceIp().split("\\."), 0, 3));
                    com.setCompanyId(a.getCompanyId());
                    com.setPriceIp(afterIp);
                    return com;
                })
                .collect(Collectors.groupingBy(SProjectCompany::getPriceIp));
        //key:CompanyId  value:重复的公司ID
        for (Map.Entry<String, List<SProjectCompany>> stringListEntry : collect.entrySet()) {
            List<SProjectCompany> values = stringListEntry.getValue();
            if(values.size()>1){
                for (SProjectCompany value : values) {
                    List<String> comIds = values.stream().map(SProjectCompany::getCompanyId).filter(companyId -> !companyId.equals(value.getCompanyId())).collect(Collectors.toList());
                    repeatMap.put(value.getCompanyId(), comIds);
                }
            }
        }
        return repeatMap;
    }

    public JSONObject projectBaseInfo(ProjectInfoPojo projectInfoPojo) {
        SProjectInfo sProjectInfo = sProjectInfoMapper.selectByPrimaryKey(projectInfoPojo.getId());
        if (sProjectInfo == null) {
            throw new BizException("不存在该项目");
        }
        if (!"true".equals(sProjectInfo.getOpen())) {
            sProjectInfo.setBudget(null);
        }
        SProjectCompany company = sProjectCompanyMapper.selectByPrimaryKey(projectInfoPojo.getValiInfo().getComId());

        Example exp = new Example(SCompanyFile.class);
        exp.createCriteria()
                .andEqualTo("bizType", bizType)
                .andEqualTo("bizId", sProjectInfo.getId())
                .andEqualTo("deleted", "n")
                .andEqualTo("fileType", "price");
        //将原来的报价单文件逻辑删除
        List<SCompanyFile> sCompanyFiles = fileMapper.selectByExample(exp);
        if (CollUtil.isEmpty(sCompanyFiles)) {
            throw new BizException("该项目未上传报价模板");
        }
        String filePath = sCompanyFiles.get(0).getFilePath();
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(sProjectInfo));
        jsonObject.put("company", company);
        jsonObject.put("template", filePath);
        return jsonObject;
    }

    private List<SProjectCompany> querySelectedProjectComs(String id) {
        SProjectCompany projectCompany = new SProjectCompany();
        projectCompany.setProjectId(id);
        projectCompany.setStatus("y");
        projectCompany.setDeleted("n");
        return sProjectCompanyMapper.select(projectCompany);
    }
    private List<SProjectCompany> queryProjectComs(String id) {
        SProjectCompany projectCompany = new SProjectCompany();
        projectCompany.setProjectId(id);
        projectCompany.setDeleted("n");
        return sProjectCompanyMapper.select(projectCompany);
    }

    private List<SAuditRecord> queryAuditRecord(String bizId) {
        Example exp = new Example(SAuditRecord.class, true, true);
        exp.createCriteria().andEqualTo("bussId", bizId).andEqualTo("bussType", bizType);
        exp.orderBy("auditDate");
        return recordMapper.selectByExample(exp);
    }

    @Autowired
    SProjectMapper projectMapper;

    public Page<ProjectInfoPojo> queryProject(ProjectQueryReqPojo reqPojo) {
        PageHelper.startPage(reqPojo.getPageNo(), reqPojo.getPageSize());
        Page<ProjectInfoPojo> projectInfoPojos = (Page<ProjectInfoPojo>) projectMapper.selectProjects(reqPojo.getParamData());
        if (CollUtil.isNotEmpty(projectInfoPojos)) {
            for (ProjectInfoPojo projectInfoPojo : projectInfoPojos) {
                projectInfoPojo.setCreatedDateStr(DateUtil.formatDateTime(projectInfoPojo.getCreatedDate()));
            }
        }
        return projectInfoPojos;
    }
    @Transactional
    public void selectSup(ProjectInfoPojo projectInfoPojo,OptVo optVo) {
        List<String> selectedIds = projectInfoPojo.getSelectedIds();

        SProjectInfo sProjectInfo = queryProjectById(projectInfoPojo);
        List<SProjectCompany> companyList = queryProjectComs(sProjectInfo.getId());
        if (CollUtil.isEmpty(companyList)) {
            throw new BizException("项目缺少供应商信息");
        }
        for (SProjectCompany projectCompany : companyList) {
            boolean contains = selectedIds.contains(projectCompany.getCompanyId());
            //更新供应商与项目关联表
            SCompanyInfo companyInfo = sCompanyInfoMapper.selectByPrimaryKey(projectCompany.getCompanyId());
            // 新增供应商若修改信息校验：供应商状态为未审核通过
            if (!ComStateEnum.PASS.name().equals(companyInfo.getState())) {
                throw new BizException(companyInfo.getName() + "供应商信息已发生变化，请待供应商信息审核通过后再进行项目审核");
            }
            //供应商标记状态审核
            if (!commonInterService.markReview(companyInfo)) {
                throw new BizException(companyInfo.getName() + "当前是非启用状态，请更换供应商！若仍需该供应商参与项目，请联系管理员！");
            }
            if (!"n".equals(companyInfo.getModId())) {
                projectCompany.setCompanyModId(companyInfo.getModId());
            }
            if (contains) {
                projectCompany.setStatus("y");
                sProjectCompanyMapper.updateByPrimaryKeySelective(projectCompany);
            }else{
                projectCompany.setStatus("n");
                sProjectCompanyMapper.updateByPrimaryKeySelective(projectCompany);
            }
        }
        //设置完供供应商，更新状态到下一个节点
        sProjectInfo.setStatus(ProjectStateEnum.sup.name());
        sProjectInfoMapper.updateByPrimaryKeySelective(sProjectInfo);
    }

    public SProjectInfo queryProjectById(String  id) {
        SProjectInfo sProjectInfo = sProjectInfoMapper.selectByPrimaryKey(id);
        if (sProjectInfo == null) {
            throw new BizException("不存在该项目");
        }
        return sProjectInfo;
    }
    public int updateProject(SProjectInfo  projectInfo) {
        return sProjectInfoMapper.updateByPrimaryKeySelective(projectInfo);
    }
    private SProjectInfo queryProjectById(ProjectInfoPojo projectInfoPojo) {
        return queryProjectById(projectInfoPojo.getId());
    }

    @Autowired
    SAuditRecordMapper recordMapper;
    @Transactional
    public CodeNameVo saveAudit(ProjectInfoPojo projectInfoPojo,OptVo optVo) {
        String url = "";
        String auditResult = projectInfoPojo.getAuditResult();
        String auditRemark = projectInfoPojo.getAuditRemark();
        SProjectInfo sProjectInfo = queryProjectById(projectInfoPojo);
        String msg;
        SProjectInfo updateModel = new SProjectInfo();
        updateModel.setId(sProjectInfo.getId());

        updateModel.setAuditUserId(optVo.getUserId());
        updateModel.setAuditUserName(optVo.getUserName());
        String auditType = "audit";
        if (ProjectStateEnum.lgd2.name().equals(sProjectInfo.getStatus())) {
            //法务复审
            if ("y".equalsIgnoreCase(auditResult)) {
                updateModel.setStatus(ProjectStateEnum.lgp2.name());
                msg = ProjectStateEnum.lgp2.getDesc();
                if (ProjectStateEnum.sif.name().equals(sProjectInfo.getHisSignState())) {
                    updateModel.setStatus(ProjectStateEnum.siw.name());
                    url= toSign(projectInfoPojo, optVo,info->{});
                }

            } else {
                updateModel.setStatus(ProjectStateEnum.lgf2.name());
                msg = ProjectStateEnum.lgf2.getDesc();
            }
            auditType = "audit2";
        }else{
            if ("y".equalsIgnoreCase(auditResult)) {
                updateModel.setStatus(ProjectStateEnum.lgd2.name());
                msg = ProjectStateEnum.lgd2.getDesc();
                sendService.sendWechat(ProjectStateEnum.lgd2.name(), optVo);
            } else {
                updateModel.setStatus(ProjectStateEnum.lgf.name());
                msg = ProjectStateEnum.lgf.getDesc();
            }
            auditType = "audit";
        }
        SAuditRecord record = addAuditRecord(optVo, sProjectInfo, auditType, auditResult, auditRemark);
        updateModel.setAuditId(record.getId());
        sProjectInfoMapper.updateByPrimaryKeySelective(updateModel);
        CodeNameVo vo = new CodeNameVo();
        vo.setId(updateModel.getId());
        vo.setCode(updateModel.getStatus());
        vo.setName(msg);
        vo.setUrl(url);
        return vo;
    }

    public void reAudit(ProjectInfoPojo projectInfoPojo, OptVo optVo) {
        String auditResult = projectInfoPojo.getAuditResult();
        String auditRemark = projectInfoPojo.getAuditRemark();
        SProjectInfo sProjectInfo = queryProjectById(projectInfoPojo);
//        addFile(projectInfoPojo,userId,sProjectInfo.getId());
        String fileType = "reAudit";

        SAuditRecord record = addAuditRecord(optVo, sProjectInfo, fileType, auditResult, auditRemark);
        addFile(projectInfoPojo, optVo.getUserId(), sProjectInfo.getId(), bizType, fileType,record.getId());
        SProjectInfo updateModel = new SProjectInfo();
        updateModel.setId(sProjectInfo.getId());
        updateModel.setAuditId(record.getId());
        updateModel.setStatus(ProjectStateEnum.lgd.name());
        sProjectInfoMapper.updateByPrimaryKeySelective(updateModel);
        sendService.sendWechat(ProjectStateEnum.lgd.name(),optVo);
    }

    @Autowired
    SCompanyFileMapper fileMapper;

    @Transactional
    public void savePriceTemplete(ProjectInfoPojo projectInfoPojo,String userId) {
        SProjectInfo sProjectInfo = queryProjectById(projectInfoPojo);
        addFile(projectInfoPojo, userId, sProjectInfo.getId(), bizType, "price","");
    }
    @Transactional
    public void savePriceList(ProjectInfoPojo projectInfoPojo, String clientIP) {
        List<String> allowState = new ArrayList<>();
        allowState.add(ProjectStateEnum.qap.name());
        allowState.add(ProjectStateEnum.lgp.name());
        allowState.add(ProjectStateEnum.lgp2.name());
        allowState.add(ProjectStateEnum.upq.name());

        ProjectInfoPojo.ValiInfo valiInfo = projectInfoPojo.getValiInfo();
        SProjectCompany projectCompany = sProjectCompanyMapper.selectByPrimaryKey(valiInfo.getComId());
        Validator.validateNotNull(projectCompany, "验证信息不存在，请重新验证企业信息");
        SProjectInfo sProjectInfo = queryProjectById(projectCompany.getProjectId());
        String status = sProjectInfo.getStatus();
        if (!allowState.contains(status)) {
            throw new BizException("当前项目状态不可再上传报价单");
        }
        projectCompany.setPriceIp(clientIP);
        projectCompany.setPriceDate(DateUtil.date());
        projectCompany.setPrice(projectInfoPojo.getComPrice());
        projectCompany.setPriceFile(projectInfoPojo.getFiles().get(0).getUrl());
        sProjectCompanyMapper.updateByPrimaryKeySelective(projectCompany);
        //记录供应商ip地址
        companyNoticeService.saveIpAddress(clientIP, IpAddressEnum.C.name(), projectCompany.getCompanyId());
    }
    public long hasAllPrice(String projectId) {
        SProjectCompany company = new SProjectCompany();
        company.setProjectId(projectId);
        company.setDeleted("n");
        List<SProjectCompany> companies = sProjectCompanyMapper.select(company);
        return companies.stream().filter(company1 -> StrUtil.isEmpty(company1.getPriceFile())).count();

    }
    /** 签报 */
    @Transactional
    public String toSign(ProjectInfoPojo projectInfoPojo,OptVo optVo) {
        return toSign(projectInfoPojo, optVo, info -> {
            info.setStatus(ProjectStateEnum.siw.name());
            sProjectInfoMapper.updateByPrimaryKeySelective(info);
        });
    }
    public String toSign(ProjectInfoPojo projectInfoPojo,OptVo optVo,Consumer<SProjectInfo> consumer) {
        for (CompanyInfoPojo company : projectInfoPojo.getCompanys()) {
            SCompanyInfo companyInfo = sCompanyInfoMapper.selectByPrimaryKey(company.getProjectCompany().getCompanyId());
            //供应商标记状态审核
            if (!commonInterService.markReview(companyInfo)) {
                throw new BizException(companyInfo.getName() + "当前是非启用状态，请更换供应商！若仍需该供应商参与项目，请联系管理员！");
            }
        }
        SProjectInfo sProjectInfo = queryProjectById(projectInfoPojo);
        List<String> passState = new ArrayList<>();
        passState.add("qa");
        passState.add("audit");
        Example exp = new Example(SAuditRecord.class, true, true);
        exp.createCriteria().andEqualTo("bussId", projectInfoPojo.getId())
                .andEqualTo("auditResult", "y")
                .andEqualTo("bussType", "project")
                .andIn("auditCat", passState);
        exp.orderBy("auditDate").desc();
        List<SAuditRecord> sAuditRecords = recordMapper.selectByExample(exp);
        if (CollUtil.isEmpty(sAuditRecords)) {
            throw new BizException("该项目没有审核通过记录无法发起签报");
        }
        Date auditDate = sAuditRecords.get(0).getAuditDate();
        long between = DateUtil.between(auditDate, DateUtil.date(), DateUnit.DAY);
        if (between > 10) {
            throw new BizException("供应商报告已过期，请重新发起项目！");
        }
        consumer.accept(sProjectInfo);
        SProjectSign addSign = new SProjectSign();
        addSign.setId(IdUtil.simpleUUID());
        addSign.setCreatedDate(DateUtil.date());
        addSign.setCreatedId(optVo.getUserId());
        addSign.setProjectId(sProjectInfo.getId());
        signMapper.insert(addSign);
        return syncDataToFeiKong(addSign, sProjectInfo);
    }
    /**
     * 同步数据到费控
     */
    public String syncDataToFeiKong(SProjectSign addSign,SProjectInfo sProjectInfo) {
        // 1.如果没有生成过项目报告，需要先生成项目报告
        //需要将所有附件都合并进来
        if (StrUtil.isEmpty(sProjectInfo.getProReport())) {
            //如果没有项目报告，需要先生成项目报告
            String projectCompanyPDF = createProjectCompanyPDF(sProjectInfo.getId());
            sProjectInfo.setProReport(projectCompanyPDF);
        }
        FeikongVo feikongVo = new FeikongVo();
        feikongVo.setSerialNo(addSign.getId());
        feikongVo.setJobNumber(sProjectInfo.getCreatedId());
        feikongVo.setTitle(sProjectInfo.getProjectName());
        List<FeikongVo.ContentDTO> content = new ArrayList<>();
        List<SProjectCompany> sProjectCompanies = querySelectedProjectComs(sProjectInfo.getId());
        if (CollUtil.isEmpty(sProjectCompanies)) {
            throw new BizException("该项目未选中供应商，无法签报");
        }
        List<String> comIds = sProjectCompanies.stream().map(SProjectCompany::getCompanyId).collect(Collectors.toList());
        Map<String, SCompanyInfo> stringSCompanyInfoMap = queryComByIds(comIds);
        for (SProjectCompany sProjectCompany : sProjectCompanies) {
            SCompanyInfo sCompanyInfo = stringSCompanyInfoMap.get(sProjectCompany.getCompanyId());
            FeikongVo.ContentDTO contentDTO = new FeikongVo.ContentDTO();
            contentDTO.setItemNumber(sProjectInfo.getId());
            contentDTO.setVendorName(sCompanyInfo.getName());
            contentDTO.setQuote(sProjectCompany.getPrice());
            content.add(contentDTO);
        }
        feikongVo.setContent(content);

        List<FeikongVo.AnnexsDTO> annexs = new ArrayList<>();
        String proReport = sProjectInfo.getProReport();
        if (StrUtil.isNotBlank(proReport)) {
            FeikongVo.AnnexsDTO annexsDTO = new FeikongVo.AnnexsDTO();
            annexsDTO.setFileBase64(obsToBaseStr(proReport));
            annexsDTO.setFileName(proReport.substring(proReport.lastIndexOf("/") + 1));
            annexs.add(annexsDTO);
        }
        feikongVo.setAnnexs(annexs);
        logger.info("请求费控报文：{}",JSON.toJSONString(feikongVo));
        String resp = HttpUtil.post(supProps.getFeikongUrl(), JSON.toJSONString(feikongVo));
        logger.info("费控返回报文：{}",resp);
        return Optional.ofNullable(resp).map(JSONObject::parseObject).map(a -> a.getString("data")).orElseThrow(() -> new BizException("同步费控系统失败"));


    }
    public String obsToBaseStr(String url) {
        HttpResponse response = HttpRequest.get(url).executeAsync();
        if (!response.isOk()) {
            logger.info("文件下载状态码:{}",response.getStatus());
            throw new BizException("文件下载错误");
        }
        byte[] bytes = response.bodyBytes();
        return Base64.encode(bytes);
    }
    public Map<String, SCompanyInfo> queryComByIds(List<String> ids) {
        Example exp = new Example(SCompanyInfo.class, true, true);
        exp.createCriteria().andIn("id", ids);
        List<SCompanyInfo> sCompanyInfos = sCompanyInfoMapper.selectByExample(exp);
        if (CollUtil.isEmpty(sCompanyInfos)) {
            throw new BizException("查询企业信息失败");
        }
        return sCompanyInfos.stream().collect(Collectors.toMap(SCompanyInfo::getId, Function.identity()));

    }
    /**
     * 发送报价单邮件
     */
    public void sendPriceEmail(ProjectInfoPojo projectInfoPojo) {
        SProjectInfo sProjectInfo = queryProjectById(projectInfoPojo);
        sProjectInfo.setStatus(ProjectStateEnum.upq.name());
        sProjectInfoMapper.updateByPrimaryKeySelective(sProjectInfo);
        sendService.notifyUpload(sProjectInfo);
    }

    private SAuditRecord addAuditRecord(OptVo optVo, SProjectInfo sProjectInfo, String fileType) {
        return addAuditRecord(optVo, sProjectInfo, fileType, null, null);

    }

    /**
     * 保存审核记录方法
     */
    private SAuditRecord addAuditRecord(OptVo optVo, SProjectInfo sProjectInfo, String fileType, String auditRes, String remark) {
        SAuditRecord record = new SAuditRecord();
        record.setId(IdUtil.simpleUUID());
        record.setBussId(sProjectInfo.getId());
        record.setBussType(bizType);
        record.setAuditCat(fileType);
        record.setAuditId(optVo.getUserId());
        record.setAuditName(optVo.getUserName());
        record.setAuditDate(DateUtil.date());
        record.setDeleted("n");
        record.setCreatedId(optVo.getUserId());
        record.setCreatedDate(DateUtil.date());
        record.setUpdateDate(DateUtil.date());
        record.setAuditRemark(remark);
        record.setAuditResult(auditRes);
        recordMapper.insert(record);
        return record;
    }

    /**
     * 保存文件方法
     */
    @Transactional
    public void addFile(ProjectInfoPojo projectInfoPojo, String userId, String bizId, String bizType, String fileType, String senBizId) {
        SCompanyFile delModel = new SCompanyFile();
        delModel.setDeleted("y");
        Example exp = new Example(SCompanyFile.class);
        exp.createCriteria()
                .andEqualTo("bizType", bizType)
                .andEqualTo("bizId", bizId)
                .andEqualTo("fileType", fileType);
        //将原来的报价单文件逻辑删除
        fileMapper.updateByExampleSelective(delModel, exp);
        List<ProjectInfoPojo.UploadFile> files = projectInfoPojo.getFiles();
        if (CollUtil.isNotEmpty(files)) {
            for (ProjectInfoPojo.UploadFile uploadFile : files) {
                SCompanyFile file = new SCompanyFile();
                file.setId(IdUtil.simpleUUID());
                file.setBizType(bizType);
                file.setBizId(bizId);
                file.setFileType(fileType);
                file.setFilePath(uploadFile.getUrl());
                file.setDeleted("n");
                file.setCreatedId(userId);
                file.setCreatedDate(DateUtil.date());
                if (StrUtil.isNotEmpty(senBizId)) {
                    file.setSenBizId(senBizId);
                }
                fileMapper.insert(file);
            }
        }

    }

    /**
     * 验证公司信息
     *
     * @param comInfoPojo 验证信息
     * @return 公司ID
     */
    public String valiComInfo(ValiComInfoPojo comInfoPojo) {
        SProjectInfo sProjectInfo = queryProjectById(comInfoPojo.getId());
        List<SProjectCompany> companyList = queryProjectComs(comInfoPojo.getId());
        if (CollUtil.isEmpty(companyList)) {
            throw new BizException("该项目暂未配置供应商");
        }
        String valiComId = "";
        for (SProjectCompany projectCompany : companyList) {
            SCompanyInfo sCompanyInfo = sCompanyInfoMapper.selectByPrimaryKey(projectCompany.getCompanyId());
            if(comInfoPojo.getName().equals(sCompanyInfo.getName())
                    && comInfoPojo.getLegalPerson().equals(sCompanyInfo.getLegalPerson())
                    && comInfoPojo.getSocialCreditCode().equals(sCompanyInfo.getSocialCreditCode())){
                valiComId = projectCompany.getId();
                break;
            }
        }
        if (StrUtil.isEmpty(valiComId)) {
            throw new BizException("公司信息验证不通过");
        }
        return valiComId;
    }

    /**
     * 验证联系人手机号
     * @param comInfoPojo 手机号
     * @return 供应商ID
     */
    public String valiPhone(ValiComInfoPojo comInfoPojo) {
        SProjectInfo sProjectInfo = queryProjectById(comInfoPojo.getId());
        List<SProjectCompany> companyList = queryProjectComs(comInfoPojo.getId());
        if (CollUtil.isEmpty(companyList)) {
            throw new BizException("该项目暂未配置供应商");
        }
        List<String> comIds = companyList.stream().map(SProjectCompany::getCompanyId).collect(Collectors.toList());
        Example exp = new Example(SCompanyContract.class, true, true);
        exp.createCriteria().andEqualTo("contactPhone", comInfoPojo.getPhone()).andIn("companyId", comIds).andEqualTo("deleted", "n");
        List<SCompanyContract> contractList = contractMapper.selectByExample(exp);
        if (CollUtil.isEmpty(contractList)) {
            throw new BizException("请使用正确的联系人手机号验真");
        }
        long count = contractList.stream().map(SCompanyContract::getCompanyId).distinct().count();
        if (count > 1) {
            throw new BizException("手机号不唯一");
        }
        String companyId = contractList.get(0).getCompanyId();
        return companyList.stream().filter(a -> a.getCompanyId().equals(companyId)).map(a -> a.getId()).findFirst().orElse("");
    }
    /**
     * 创建项目公司PDF
     *
     * @param id 项目ID
     * @return 报告链接
     */
    public String createProjectCompanyPDF(String id) {
        ProjectInfoPojo projectInfoPojo = detail(id,false);
        String projectCatName = commonBizService.transCat(projectInfoPojo.getProjectCat());
        List<CompanyInfoPojo> companys = projectInfoPojo.getCompanys();
        for (CompanyInfoPojo company : companys) {
            String authLetterEffectDate = company.getAuthLetterEffectDate();
            if (StrUtil.isNotEmpty(authLetterEffectDate)) {
                authLetterEffectDate = authLetterEffectDate.replace(",", "至");
                company.setAuthLetterEffectDate(authLetterEffectDate);
            }
            // 新增供应商若修改信息校验：供应商修改中且供应商状态为未审核通过
            if ("Y".equalsIgnoreCase(company.getModified()) && !ComStateEnum.PASS.name().equals(company.getState())) {
                throw new BizException(company.getName() + "供应商信息已发生变化，请待供应商信息审核通过后再进行项目审核");
            }
        }
        Map<String, Object> dataMap = JSONObject.parseObject(JSONObject.toJSONString(projectInfoPojo, SerializerFeature.WriteDateUseDateFormat), Map.class);
        dataMap.put("projectCatName", projectCatName);
        String proposedUseDate = projectInfoPojo.getProposedUseDate();
        if (StrUtil.isNotEmpty(proposedUseDate)) {
            proposedUseDate = proposedUseDate.replace(",", "至");
            dataMap.put("proposedUseDate", proposedUseDate);
        }
        String filePath = "";
        logger.info("===={}",JSON.toJSONString(dataMap));
//        try (ByteArrayInputStream inputStream = new ByteArrayInputStream(pdfUtil.getPdfStream("companyPDF.html", dataMap).toByteArray())) {
//            filePath = obsUtil.uploadStream(inputStream, "project/pdf", true, projectInfoPojo.getId() + "-"+IdUtil.simpleUUID() + ".pdf");
//            filePath = CdnEncryUtil.toObsUrl(filePath);
//            logger.info("供应商报告url:{}", filePath);
//            updateReport(id, filePath);
//        } catch (IOException e) {
//            logger.info("PDF数组转流异常");
//            logger.info(e.getMessage());
//        }
        return filePath;
    }

    List<String> signState = new ArrayList<>();
    {
        signState.add(ProjectStateEnum.siw.name());
        signState.add(ProjectStateEnum.sid.name());
        signState.add(ProjectStateEnum.sif.name());
        signState.add(ProjectStateEnum.sip.name());
    }
    /**
     * 同步项目签约状态
     *
     * @param id 项目ID
     * @param state 项目状态
     */
    @Transactional
    public void syncSignState(String id, String state) {
        SProjectSign sProjectSign = signMapper.selectByPrimaryKey(id);
        if (sProjectSign == null) {
            throw new BizException("不存在该项目");
        }
        SProjectInfo sProjectInfo = sProjectInfoMapper.selectByPrimaryKey(sProjectSign.getProjectId());
        if (sProjectInfo == null) {
            throw new BizException("不存在该项目");
        }
        boolean contains = signState.contains(state);
        if (!contains) {
            throw new BizException("状态不在范围");
        }
        sProjectInfo.setStatus(state);
        sProjectInfo.setHisSignState(state);
        sProjectInfoMapper.updateByPrimaryKeySelective(sProjectInfo);
        sProjectSign.setSignState(state);
        sProjectSign.setSignDate(DateUtil.date());
        signMapper.updateByPrimaryKeySelective(sProjectSign);
        if (ProjectStateEnum.sif.name().equals(state)) {
            // 签报驳回时清空项目供应商关联表中的修改标识
            sCompanyMapper.updateCompanyModifyId(null, sProjectSign.getProjectId(), null);
        }
    }
    public void clearReport(String id) {
        projectMapper.clearReport(id);
    }

}
